﻿using System;
using System.Collections.Generic;
using System.Linq;
using Way.Bus.Controllers;
using Way.Bus.WMS.Model;
using Way.Contract;
using Way.Contract.Center;
using Way.Contract.Data.ControllerData;
using Way.Contract.MVC;
using Way.EAP.DataAccess.Entity;
using Way.Bus.Model;
using Way.Contract.Data;
using Way.Bus.WMS.Controllers;
using Way.EAP.DataAccess.Regulation;
using Way.Bus.WMS.ST.Model;
using System.Data;
using Way.EAP.DataAccess.Data;

namespace Way.Bus.WMS.ST.Controllers.OutOrder
{
    public class ST_OutOrderController : StockOutOrderController
    {
        public ST_OutOrderController() : base(new StockOutOrder()) { }
        public ST_OutOrderController(IModel model) : base(model) { }
        /// <summary>
        /// 描述：ST基础出库控制器
        /// 作者：fisher
        /// 创建日期:2014-05-11
        /// </summary>

        #region 基础设置

        protected override string OnGetPath()
        {
            return "Views/ST/OutOrder/OutOrder.htm";
        }

        protected static void InitOrder(Way.Contract.Data.ModelData data, Way.Contract.Data.ItemData item)
        {

            if (item.IsField("rowindex"))
                item.isedit = false;
            //修改弹出窗口的title
            data.title = "出库单";
            //隐藏属性信息
            if (item.IsField("OfficeWorker")
                  || item.IsField("SourceOutCode")
                  || item.IsField("LogCode")
                  || item.IsField("FINISHTIME")
                  || item.IsField("STOCKTYPE")
                  || item.IsField("IsDisable")
                  || item.IsField("SourceName")
                  || item.IsField("Reviewedby")
                  || item.IsField("Revieweddate")
                  || item.IsField("IsReviewed")
                || item.IsField("INOUTTIME")
                || item.IsField("BUMEN")
                || item.IsField("RowIndex")
            )
                item.visible = false;
            if (item.IsField("CLIENTNO"))
            {
                item.title = "客户";
                item.disabled = true;
            }
            if (item.IsField("WORKERID"))
            {
                item.visible = false;
            }
            //设置不可写
            if (item.IsField("CODE"))
            {
                item.disabled = true;
                item.index = 1;
                item.title = "出库单号";
            }
            if (item.IsField("SourceCode"))
                item.disabled = true;
            if (item.IsField("STATE"))
            {
                item.disabled = true;
            }
            //设置显示顺序
            if (item.field=="REMARK")
                item.index = 4;
            if (item.field == "CREATEDBY")
                item.index = 5;
            if (item.field == "CREATIONDATE")
                item.index = 6;


        }
        public static void InitOrderMaterials(Way.Contract.Data.ModelData data, Way.Contract.Data.ItemData item)
        {

            data.title = "出库单明细";
            if (item.IsField("PARENTID")
                 || item.IsField("SourceCode")
                 || item.IsField("STATE")
                //|| item.IsField("BATCHNO")
                 || item.IsField("BUMEN")
                 || item.IsField("WORKERID")
                 || item.IsField("IsDisable")
                 || item.IsField("code")
                 || item.IsField("Reviewedby")
                 || item.IsField("Revieweddate")
                 || item.IsField("Submitedby")
                 || item.IsField("IsReviewed")
                 || item.IsField("IsSubmited")
                 || item.IsField("Submiteddate")
                //|| item.IsField("SENBATCHNO")
                 || item.IsField("PORTNAME")
                 || item.IsField("ISCHECKOK")
                 || item.IsField("MWEIGHT") || item.IsField("SINGLEWEIGHT") || item.IsField("FINISHNUM") || item.IsField("STAYNUM")
                )
                item.visible = false;
            if (item.IsField("MATERIALCODE"))
            {
                item.title = "货物名称";
                if (item.foreign != null)
                {
                    item.foreign.rowdisplay.Add("FMODEL", "FMODEL");//规格型号
                    item.foreign.rowdisplay.Add("CODE", "MCODE");//物资编码
                }
            }
            if (item.IsField("MCODE"))
            {
                item.title = "货物编码";
                item.disabled = true;
            }
            if (item.IsField("SENBATCHNO"))
                item.title = "有效期";
            if (item.IsField("DEPOTWBS"))
                item.required = true;
            if (item.IsField("FMODEL")
                  || item.IsField("Createdby")
                 || item.IsField("Creationdate")
                )
            {
                item.disabled = true;
            }

        }
        /// <summary>
        /// 初始化显示与否
        /// </summary>
        /// <param name="data"></param>
        /// <param name="item"></param>
        protected override void OnInitViewChildItem(Way.Contract.Data.ModelData data, Way.Contract.Data.ItemData item)
        {
            base.OnInitViewChildItem(data, item);
            if (data.name.EndsWith("OutOrder"))
                InitOrder(data, item);
            if (data.name.EndsWith("StockOutOrderMaterials"))
            {
                InitOrderMaterials(data, item);
                if (item.IsField("STAY3"))
                {
                    item.visible = true;
                    item.title = "生产日期";
                    item.index = 14;

                }
                if (item.IsField("STAY4"))
                {
                    item.visible = true;
                    item.title = "许可年份";
                    item.index = 15;
                }
                if (item.IsField("STAY5"))
                {
                    item.visible = true;
                    item.title = "许可证号";
                    item.index = 16;
                }
            }
            if (data.name.EndsWith("StockOutNoticeMaterials"))
            {
                ST_OutNoticeController.InitOutNoticeMaterials(data, item);
                if (item.IsField("parentid"))
                {
                    item.visible = false;
                    item.foreign.isfkey = true;
                    item.foreign.foreignfiled = "SOURCEID";
                    item.foreign.filedname = item.field;
                    //item.foreign.displayfield = ("ModelName").ToUpper();显示的名称
                    item.foreign.objectname = data.name;
                    item.foreign.foreignobject = "Way.Bus.WMS.Model.StockOutOrder";
                    item.foreign.tablename = "Acc_WMS_OutOrder";
                }
              
            }
            if (data.name.EndsWith("Sequence"))
            {
                data.visible = true;
                if (item.IsField("SEQUENCECODE"))
                    item.visible = true;
                else
                    item.visible = false;
            }
        }

        #endregion

        [ActionCommand(name = "导出", title = "导出", index = 10, icon = "icon-down", isselectrow = false, onclick = "emport5")]
        public void Emport()
        {
            //ExcelDRController er = new ExcelDRController();
            //er.bc = this;
        }

        //去掉“单据创建人与登陆人一致”的限制
        //protected override void OnRemoveing(ControllerBase.SaveEvent item)
        //{
        //    BasicInfo sio = item.Item as BasicInfo;
        //    if (sio.Createdby == this.user.ID)
        //    {
        //        base.OnRemoveing(item);
        //    }
        //    else
        //    {
        //        throw new Exception("单据创建人与当前登陆人不符，不能删除！！");
        //    }
        //}

        protected override void Remove()
        {
            base.Remove();
            //置发货通知及出库单状态
            setState((StockOutOrder)this.ActionItem);
        }

        protected override void OnSubmitData(BasicInfo info)
        {
            StockOutOrder so = info as StockOutOrder;
            if (so.IsSubmited == true)
            {
                throw new Exception("异常：单据已提交不能重复提交！");
            }
            so.Materials.DataAction = this.model.GetDataAction();
            so.Materials.GetData();
            if (so.Materials.Count == 0)
            {
                throw new Exception("单据无明细数据不能提交！");
            }
            if (so.Materials.Exists(delegate(StockOutOrderMaterials soom) { return string.IsNullOrEmpty(soom.Createdby); }))
                throw new Exception("异常：发货明细行中检测到有空的库管，不能提交，必须库管人员操作后才可提交！");
            so.STATE = 2;
            
            base.OnSubmitData(info);
            //setStatus(info);
        }

        protected override void OnEdited(EntityBase item)
        {
            base.OnEdited(item);
            setState((StockOutOrder)item);
        }
        public void setState(StockOutOrder order)
        {
            StockOutNoticeMaterials snm = new StockOutNoticeMaterials();
            string tn = ((IEntityBase)snm).GetSearchSQL();
            string sql = "select parentid, SUM(a.STAYNUM) dcnum, sum(a.FINISHNUM) ycnum,sum(a.num) num from (" + tn + ") a where a.PARENTID={0}"
            + "group by a.PARENTID";
            IDataAction action = this.model.GetDataAction();
            DataTable tb = action.GetDataTable(string.Format(sql, order.SourceID));
            if (tb.Rows.Count > 0)
            {
                int st = 0;
                double dc = double.Parse(tb.Rows[0]["dcnum"].ToString());
                double yc = double.Parse(tb.Rows[0]["ycnum"].ToString());
                double num = double.Parse(tb.Rows[0]["num"].ToString());
                if (yc > 0 && yc < num)
                    st = 1;
                if (yc > 0 && yc >= num)
                    st = 2;
                action.StartTransation();
                string sql1 = "update Acc_WMS_OutNotice set STATE='" + st + "' where ID = '" + order.SourceID + "'";
                string sql2 = "update " + order.ToString() + " set STATE='" + st + "' where SourceID = '" + order.SourceID + "'";
                if (st == 1)
                {
                    string sql3 = "select PackID from Acc_WMS_OutNotice where ID=" + order.SourceID;
                    object obj = action.GetValue(sql3);
                    if (obj != null && !string.IsNullOrEmpty(obj.ToString()))
                    {
                        int packid = int.Parse(obj.ToString());
                        if (packid > 0)
                        {
                            string sql5 = "select State from ST_PackList where id=" + packid;
                            object state = action.GetValue(sql5);
                            if (state != null && !string.IsNullOrEmpty(state.ToString()))
                            {
                                int sta = int.Parse(state.ToString());
                                if (sta == 2)
                                {
                                    string sql4 = "update ST_PackList set State=1 where state>1 and id=" + packid;
                                    action.Execute(sql4);
                                }
                                if (sta > 2)
                                {
                                    throw new Exception("异常：出库单" + order.Code + ",已在运输中，不能修改！");
                                }
                            }
                        }
                    }
                }
                action.Execute(sql1);
                action.Execute(sql2);
                action.Commit();
                action.EndTransation();
            }
        }
        //设置出库通知状态：0、未出货；1、部分出货；2、出货完成
        //设置出库单状态：0、未出货；1、部分出货；2、出货完成
        public void setStatus(EntityBase item)
        {
            StockOutOrder order = item as StockOutOrder;
            IDataAction action = this.model.GetDataAction();

            string state = "0";
            if (order.Materials.Count == 0)
            {
                order.Materials.DataAction = this.model.GetDataAction();
                order.Materials.GetData();
            }
            try
            {
                //从数据库查询入库情况
                string sqlSelect = "select t1.PARENTID," +
                                    "   sum(isnull(t1.NUM,0)) as NUM," +
                                    "   sum(isnull(t2.NUM,0)) as NUM1," +
                                    "   sum(isnull(t1.NUM,0)-isnull(t2.NUM,0)) as STAYNUM " +
                                    "from (" +
                                    "select PARENTID,ID,sum(NUM) as NUM " +
                                    "from Acc_WMS_OutNoticeMaterials t1 " +
                                    "group by PARENTID,ID " +
                                    ") t1 " +
                                    "left join (" +
                                    "select SourceID,SourceRowID,sum(NUM) as NUM " +
                                    "from Acc_WMS_OutOrderMaterials t1 " +
                                    "group by SourceID,SourceRowID " +
                                    ") t2 " +
                                    "on t1.PARENTID = t2.SourceID " +
                                    "and t1.ID = t2.SourceRowID " +
                                    "where t1.PARENTID  = '" + order.SourceID + "' " +
                                    "group by t1.PARENTID ";
                action.StartTransation();
                DataTable oldDataTable = action.GetDataTable(sqlSelect);
                foreach (DataRow oldRow in oldDataTable.Rows)
                {
                    if (Convert.ToInt16(oldRow["NUM"]) > 0)
                    {
                        if (Convert.ToInt16(oldRow["STAYNUM"]) > 0 && Convert.ToInt16(oldRow["STAYNUM"]) < Convert.ToInt16(oldRow["NUM"]))
                            state = "1";
                        else if (Convert.ToInt16(oldRow["STAYNUM"]) == 0)
                            state = "2";
                    }

                }
                if (order.Materials.Count > 0 && (order.SourceCode == null || order.SourceCode == ""))
                {
                    state = "2";
                }
                string sql = "update " + order.ToString() + " set STATE='" + state + "' where SourceID = '" + order.SourceID + "'";
                action.Execute(sql);
                sql = "update Acc_WMS_OutNotice set STATE='" + state + "' where ID = '" + order.SourceID + "'";
                action.Execute(sql);
                action.Commit();
            }
            catch (Exception err)
            {
                throw err;
            }
            finally
            {
                action.EndTransation();
            }

        }
        /// <summary>
        /// 外键查询初始化界面显示
        /// </summary>
        /// <param name="model"></param>
        /// <param name="data"></param>
        protected override void OnForeignIniting(IModel model, InitData data)
        {
            base.OnForeignIniting(model, data);
            if (this.fdata.filedname == "MATERIALCODE")
            {
                if (this.ActionItem != null && this.ActionItem["SOURCEID"] != null && this.ActionItem["SOURCEID"].ToString() != "")
                {
                    IModel md = new StockOutNoticeMaterials();
                    data.modeldata = md.GetModelData();

                    foreach (ItemData d in data.modeldata.childitem)
                    {
                        ST_OutNoticeController.InitOutNoticeMaterials(data.modeldata, d);
                    }
                }
                else
                {
                    foreach (ItemData d in data.modeldata.childitem)
                    {
                        Way.Bus.WMS.ST.Controllers.Custemer.MaterialsController.InitMaterials(data.modeldata, d);
                    }
                }
            }
            //if (this.fdata.filedname == "DEPOTWBS")
            //{
            //    foreach (ItemData d in data.modeldata.childitem)
            //    {
            //        if (d.IsField("MCODE") || d.IsField("MNAME") || d.IsField("model"))
            //            d.visible = false;
            //    }
            //}
        }

        protected override ReadTable OnForeignLoad(IModel model, loadItem item)
        {
            //选择商品
            if (this.fdata.filedname == "MATERIALCODE")
            {
                if (this.ActionItem["SOURCEID"] != null && this.ActionItem["SOURCEID"].ToString() != "")
                {
                    StockOutNoticeMaterials oom = new StockOutNoticeMaterials();
                    if (oom != null)
                    {
                        item.rowsql = ((IEntityBase)oom).GetSearchSQL() + " where parentid=" + this.ActionItem["SOURCEID"].ToString();
                    }
                }
                else
                    item.rowsql = Common.GetNoticeMaterialsSQL(item.rowsql, "");
            }
            if (this.fdata.filedname == "PARENTID" && this.fdata.objectname.EndsWith("StockOutNoticeMaterials"))
            {
                item.rowsql = Common.GetMaterialsBatchSQL(item.rowsql);
            } if (this.fdata.filedname == "PARENTID" && this.fdata.objectname.EndsWith("StockOutOrderMaterials"))
            {
                item.rowsql = Common.GetMaterialsBatchSQL(item.rowsql);
                if (string.IsNullOrEmpty(item.sort))
                    item.sort = "creationdate,f2 desc";

            }
            return base.OnForeignLoad(model, item);
        }
        protected override void OnForeignLoaded(IModel model, ReadTable table)
        {
            if (this.fdata.filedname == "MATERIALCODE")
            {
                if (this.ActionItem["SOURCEID"] != null && this.ActionItem["SOURCEID"].ToString() != "")
                {
                    StockOutNoticeMaterials oom = new StockOutNoticeMaterials();
                    string fname = oom.GetAppendPropertyKey("MATERIALCODE");
                    table.rows.Columns.Add("FNAME");
                    table.rows.Columns.Add("CODE");
                    foreach (DataRow r in table.rows.Rows)
                    {
                        r["STAY1"] = r["ID"];
                        r["ID"] = r["MATERIALCODE"];
                        r["FNAME"] = r[fname];
                        r["CODE"] = r["MCODE"];
                    }
                }
            }
            base.OnForeignLoaded(model, table);
        }

        [WhereParameter]
        public string NoticeId { get; set; }
        public string GetNoticeStayGrid()
        {
            EntityList<StockOutNoticeMaterials> List1 = new EntityList<StockOutNoticeMaterials>(this.model.GetDataAction());
            EntityList<StockOutNotice> soList = new EntityList<StockOutNotice>(this.model.GetDataAction());
            soList.GetData("code='" + NoticeId + "'");
            List1.GetData("parentId='" + soList[0].ID + "'");
            List<StockOutNoticeMaterials> list = new List<StockOutNoticeMaterials>();
            list = List1;
            string str = JSON.Serializer(list.ToArray());
            return str;
        }

        [ActionCommand(name = "生成出库明细", index = 1, isselectrow = true, ischild = true, childmodel = "Way.Bus.WMS.Model.StockOutNoticeMaterials", icon = "icon-works")]
        public void SetStockOut()
        {
            if (!string.IsNullOrEmpty(this.Tag))
            {
                EntityList<StockOutNoticeMaterials> items = JSON.Deserialize<EntityList<StockOutNoticeMaterials>>(this.Tag);
                items.DataAction = this.model.GetDataAction();
                if (items != null)
                {
                    Materials m;
                    StockOutOrder order = this.ActionItem as StockOutOrder;
                    EntityList<StockOutOrderMaterials> stockout = order.Materials;
                    stockout.DataAction = this.model.GetDataAction();
                    StockOutOrderMaterials om = null;
                    StockInfoMaterials info = null;
                    OutInSequence ois = null;
                    foreach (StockOutNoticeMaterials item in items)
                    {
                        m = item.GetForeignObject<Materials>(this.model.GetDataAction());
                        if (m.SEQUENCECODE)
                        {
                            SetStockOutSeq(order, item, stockout, om, info, ois);
                            continue;
                        }
                        SetStockOutItems(m, order, item, stockout, om, info);
                    }
                    stockout.Save();
                }
            }
        }
        private void SetStockOutSeq(StockOutOrder order, StockOutNoticeMaterials item, EntityList<StockOutOrderMaterials> stockout, StockOutOrderMaterials om, StockInfoMaterials info, OutInSequence ois)
        {
            //item.OutSequence.DataAction = this.model.GetDataAction();
            item.OutSequence.GetData();
            foreach (OutNoticeSequence seq in item.OutSequence)
            {
                info = StockInfoMaterials.GetStock(seq.SEQUENCECODE);
                if (info == null)
                    throw new Exception("异常：第" + item.RowIndex + "行中要求发放的序列号" + seq.SEQUENCECODE + ",在库存中不存在，不能发放！");
                if (info.Code != item.MATERIALCODE)
                    throw new Exception("异常：第" + item.RowIndex + "行中要求发放的序列号" + seq.SEQUENCECODE + ",在库存中的商品类型于通知明细中的商品类型不同，不能发放！");
                if (info.WAREHOUSEID != order.TOWHNO)
                    throw new Exception("异常：第" + item.RowIndex + "行中要求发放的序列号" + seq.SEQUENCECODE + ",不在出库单选择仓库中，不能发放！");
                om = stockout.Find(delegate(StockOutOrderMaterials soom)
                {
                    return soom.STAY7.Equals(info.ID);
                });
                if (om == null)
                {
                    om = new StockOutOrderMaterials();
                    om.SourceRowID = item.ID;
                    om.SourceID = item.PARENTID;
                    om.SourceTable = item.ToString();
                    om.PARENTID = order.ID;
                    om.MATERIALCODE = info.Code;
                    om.BATCHNO = info.BATCHNO;
                    om.DEPOTWBS = info.DEPOTWBS;
                    om.MCODE = info.MCODE;
                    om.NUM = 1;
                    om.SENBATCHNO = info.SENBATCHNO;
                    om.FMODEL = info.FMODEL;
                    om.STAY7 = info.ID;
                    stockout.Add(om);

                }
                else
                {
                    om.NUM += 1;
                }
                ois = new OutInSequence();
                ois.SEQUENCECODE = seq.SEQUENCECODE;
                om.OutInSequence.Add(ois);
            }
        }
        private void SetStockOutItems(Materials m,StockOutOrder order, StockOutNoticeMaterials item, EntityList<StockOutOrderMaterials> stockout, StockOutOrderMaterials om, StockInfoMaterials info)
        {
            double ffnum = item.STAYNUM;
            if (ffnum > 0)
            {
                string str = StockInfoView.GetStockSQL(0, order.TOWHNO, int.Parse(item.MATERIALCODE), 0, item.BATCHNO);
                str = "select * from (" + str + ") a where 1=1";
                string ord = "dcode,kynum,id";
                if (m.BATCH)
                {
                    str = str + " and batchno='" + item.BATCHNO + "'";
                    ord = "batchno," + ord;
                }
                if (m.ISPERIOD)
                    ord = "subno," + ord;
                str = str + " and kynum>0 order by " + ord;
                DataTable table = this.model.GetDataAction().GetDataTable(str);
                foreach (DataRow r in table.Rows)
                {
                    om = new StockOutOrderMaterials();
                    om.SourceRowID = item.ID;
                    om.SourceID = item.PARENTID;
                    om.SourceTable = item.ToString();
                    om.PARENTID = order.ID;
                    om.MATERIALCODE = item.MATERIALCODE;
                    om.BATCHNO = item.BATCHNO;
                    om.DEPOTWBS = r["did"].ToString();
                    om.MCODE = item.MCODE;
                    om.SENBATCHNO = r["SUBNO"].ToString();
                    om.FMODEL = item.FMODEL;
                    om.STAY7 = double.Parse(r["ID"].ToString());
                    double kynum = double.Parse(r["kynum"].ToString());
                    if (kynum >= ffnum)
                    {
                        om.NUM = ffnum;
                        ffnum = 0;
                    }
                    else
                    {
                        om.NUM = kynum;
                        ffnum = ffnum - kynum;
                    }
                    stockout.Add(om);
                    if (ffnum <= 0)
                        break;
                }
            }
        }
    }
    
}
